/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.transas.zorlog.flightgear;

import com.transas.zorlog.data.DataSource;
import com.transas.zorlog.data.LowPassFilter;
import com.transas.zorlog.data.Modificator;
import com.transas.zorlog.data.Retriever;
import java.io.IOException;
import java.net.*;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Sends UDP packets to FlightGear via generic text protocol.
 * @author amalikov
 */
public class FlightGearSender {

	public FlightGearSender(
			String addr, int port, String self,
			String latitude, String longitude, String altitude, String airspeed,
			String roll, String pitch, String heading,
			String aileron, String elevator, String rudder, String throttle, String flaps,
			String rpm, String gspeed, String baroalt, String vspeed, String aoa, String slip, double filterAlpha, double offset) {
		this.port = port;
        try {
            socket = new DatagramSocket(new InetSocketAddress(self, 0));
            this.addr = InetAddress.getByName(addr);
        } catch (SocketException | UnknownHostException e) {
        }
		
		final Modificator flapsModificator = new Modificator(){
			@Override
			public double get(double v) {
				if (v < 1)
					return 0;
				else if (v < 2)
					return 0.349;
				else
					return 1;
			}
		};
		
		retrievers = new ArrayList<>();
		
		retrievers.add(new Retriever(latitude, 1, new LowPassFilter(filterAlpha)));
		retrievers.add(new Retriever(longitude, 1, new LowPassFilter(filterAlpha)));
		retrievers.add(new Retriever(altitude, 1 / 0.3048, new LowPassFilter(filterAlpha), offset));
		
		retrievers.add(new Retriever(roll));
		retrievers.add(new Retriever(pitch));
		retrievers.add(new Retriever(heading));
		
		retrievers.add(new Retriever(airspeed, 1 / 1.852));
		
		retrievers.add(new Retriever(aileron));
		retrievers.add(new Retriever(elevator, -1));
		retrievers.add(new Retriever(rudder));
		retrievers.add(new Retriever(throttle));
		retrievers.add(new Retriever(flaps, 1, flapsModificator));
		
		retrievers.add(new Retriever(aileron));
		retrievers.add(new Retriever(aileron, -1));
		retrievers.add(new Retriever(elevator, -1));
		retrievers.add(new Retriever(elevator, -1));
		retrievers.add(new Retriever(flaps, 1, flapsModificator));
		
		retrievers.add(new Retriever(rpm));
		
		retrievers.add(new Retriever(gspeed, 1 / 1.852));
		retrievers.add(new Retriever(baroalt, 1 / 0.3048));
		retrievers.add(new Retriever(vspeed, 1 / 0.3048));
		retrievers.add(new Retriever(aoa));
		retrievers.add(new Retriever(slip));
	}

    public void send(DataSource ds, int position) {
		NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
		nf.setGroupingUsed(false);
		nf.setMinimumFractionDigits(0);
		nf.setMaximumFractionDigits(20);

        String str = new String();		
		
		for (Retriever r : retrievers)
			str += nf.format((double)r.get(ds, position)) + "\t";
		
		str += "\n";

        try {
			byte[] buf = str.getBytes();
            socket.send(new DatagramPacket(buf, buf.length, addr, port));
        } catch (IOException e) {
        }
    }
	
    private DatagramSocket socket = null;
    private InetAddress addr = null;
    private int port = 5558;
	
	private List<Retriever> retrievers;
}

